﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Vit.Common.Extensions;

namespace Vit.Data
{
    public abstract class EntityBase
    {
        protected List<EntityProperty> properties;

        public EntityBase()
        {
            properties = new List<EntityProperty>();
        }

        public virtual T GetProperty<T>(string name)
        {
            return GetProperty(name, default(T));
        }

        public virtual T GetProperty<T>(string name, T defaultValue)
        {
            object val = GetProperty(name, null);
            if (val == null)
                return defaultValue;
            return val.ConvertTo<T>(defaultValue);
        }

        public virtual object GetProperty(string name, object defaultValue)
        {
            var prop = properties.FirstOrDefault(o => string.Equals(name, o.Name, StringComparison.OrdinalIgnoreCase));
            if (prop != null)
                return prop.Value;
            return defaultValue;
        }

        public virtual void SetProperty(string name, object value)
        {
            SetProperty(name, value, EntityState.New, EntityState.Updated);
        }

        public virtual void SetProperty(string name, object value, EntityState addState, EntityState updateState)
        {
            var propInfo = this.GetType().GetProperty(name);
            Type propType = propInfo.PropertyType;
            var prop = properties.FirstOrDefault(o => string.Equals(name, o.Name, StringComparison.OrdinalIgnoreCase));
            if (propType.IsGenericType)
            {
                propType = propType.GetGenericArguments()[0];
            }

            object val = value.ConvertTo(propType, null);
            if (prop == null)
            {
                prop = new EntityProperty()
                {
                    Name = name,
                    Value = val,
                    OriginalValue = val,
                    State = addState
                };
                properties.Add(prop);
            }
            else
            {
                prop.Value = val;
                prop.State = updateState;
            }
        }
    }
}
